//
// Created by DELL on 2023/12/13.
//

#pragma once

#include <Windows.h>
#include <mutex>
#include <functional>
#include "glad/glad_wgl.h"

class WglContext
{
public:
    ~WglContext();

    static std::shared_ptr<WglContext> create(int width, int height);

    [[nodiscard]] HWND getHWnd() const { return this->hwnd; }

    void makeCurrent();

    void bind();
    void unbind();
    bool update();
    void swapBuffer();
    void setSwapInterval(int interval);

    void setResizeCallback(std::function<void(int width, int height)> callback)
    {
        this->resizeCallback = std::move(callback);
    }

    [[nodiscard]] bool getClosed() const { return this->closed; }

private:
    explicit WglContext(int width, int height);

    static void APIENTRY debugOutputCallback(GLenum source, GLenum type, unsigned int id, GLenum severity,
                                             GLsizei length, const char *message, const void *userParam);
    static HWND createWindow(int width, int height);
    static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

    HDC hdc{};
    HWND hwnd{};
    HGLRC context = nullptr;
    MSG msg { };
    int width{};
    int height{};
    std::recursive_mutex lock;
    std::function<void(int width, int height)> resizeCallback;
    bool closed{false};
};

